package com.darling.danotebackend.utils;

import java.awt.*;

/**
 * 工具类：计算颜色相似度
 *
 * @author wzd
 */
public final class ColorSimilarUtils {

    private ColorSimilarUtils() {
    }

    // RGB空间最大欧氏距离 ( sqrt( 3 * 255² ) )
    private static final double MAX_RGB_DISTANCE = Math.sqrt(3 * 255.0 * 255.0);

    /**
     * 计算两个十六进制颜色在RGB空间的欧几里得距离
     * 距离越小表示颜色越相似
     *
     * @param color1 第一个颜色，格式如 "#FF0000" 或 "FF0000"
     * @param color2 第二个颜色，格式如 "#CC0000" 或 "CC0000"
     * @return 欧几里得距离 (0-441.67)
     */
    private static double calculateRgbDistance(String color1, String color2) {
        Color c1 = parseColor(color1);
        Color c2 = parseColor(color2);
        return calculateRgbDistance(c1, c2);
    }

    /**
     * 计算两个Color对象在RGB空间的欧几里得距离
     */
    public static double calculateRgbDistance(Color c1, Color c2) {
        int rDiff = c1.getRed() - c2.getRed();
        int gDiff = c1.getGreen() - c2.getGreen();
        int bDiff = c1.getBlue() - c2.getBlue();
        return Math.sqrt(rDiff * rDiff + gDiff * gDiff + bDiff * bDiff);
    }

    /**
     * 计算两个颜色在RGB空间的相似度百分比
     *
     * @param color1 第一个颜色
     * @param color2 第二个颜色
     * @return 相似度百分比 (0-100)，值越大越相似
     */
    public static double calculateRgbSimilarityPercentage(Color color1, Color color2) {
        double distance = calculateRgbDistance(color1, color2);
        double similarity = 1.0 - (distance / MAX_RGB_DISTANCE);
        return Math.max(0, Math.min(100, similarity * 100)); // 确保在0-100范围内
    }

    /**
     * 计算两个颜色在HSB空间的综合差异度
     * 更关注色相(Hue)的相似性
     *
     * @param color1 第一个颜色
     * @param color2 第二个颜色
     * @return 差异度 (0-1)，值越小越相似
     */
    private static double calculateHsbDifference(String color1, String color2) {
        Color c1 = parseColor(color1);
        Color c2 = parseColor(color2);
        return calculateHsbDifference(c1, c2);
    }

    /**
     * 计算两个Color对象在HSB空间的综合差异度
     */
    public static double calculateHsbDifference(Color c1, Color c2) {
        float[] hsb1 = Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), null);
        float[] hsb2 = Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(), null);

        // 计算色相环上的最短距离
        float hueDiff = Math.min(
                Math.abs(hsb2[0] - hsb1[0]),
                1.0f - Math.abs(hsb2[0] - hsb1[0])
        );

        // 饱和度和亮度差异
        float saturationDiff = Math.abs(hsb2[1] - hsb1[1]);
        float brightnessDiff = Math.abs(hsb2[2] - hsb1[2]);

        // 加权综合差异 (可根据实际需求调整权重)
        // 色相权重最高，饱和度次之，亮度最低
        return 0.6 * hueDiff + 0.3 * saturationDiff + 0.1 * brightnessDiff;
    }

    /**
     * 计算两个颜色的余弦相似度
     * 值越接近1表示方向越相似（对亮度变化不敏感）
     *
     * @param color1 第一个颜色
     * @param color2 第二个颜色
     * @return 余弦相似度 (0-1)
     */
    public static double calculateCosineSimilarity(String color1, String color2) {
        Color c1 = parseColor(color1);
        Color c2 = parseColor(color2);

        int r1 = c1.getRed(), g1 = c1.getGreen(), b1 = c1.getBlue();
        int r2 = c2.getRed(), g2 = c2.getGreen(), b2 = c2.getBlue();

        double dotProduct = r1 * r2 + g1 * g2 + b1 * b2;
        double magnitude1 = Math.sqrt(r1 * r1 + g1 * g1 + b1 * b1);
        double magnitude2 = Math.sqrt(r2 * r2 + g2 * g2 + b2 * b2);

        if (magnitude1 == 0 || magnitude2 == 0) {
            return 0.0; // 避免除零
        }

        return dotProduct / (magnitude1 * magnitude2);
    }

    /**
     * 将十六进制颜色字符串解析为Color对象
     *
     * @param hexColor 颜色字符串，支持 "#RRGGBB" 或 "RRGGBB" 格式
     * @return Color对象
     * @throws IllegalArgumentException 当格式不正确时
     */
    private static Color parseColor(String hexColor) {
        if (hexColor == null || hexColor.isEmpty()) {
            throw new IllegalArgumentException("颜色字符串不能为空");
        }

        // 去除#号
        String hex = hexColor.startsWith("#") ? hexColor.substring(1) : hexColor;

        if (hex.length() != 6) {
            throw new IllegalArgumentException("颜色字符串必须是6位十六进制数: " + hexColor);
        }

        try {
            int r = Integer.parseInt(hex.substring(0, 2), 16);
            int g = Integer.parseInt(hex.substring(2, 4), 16);
            int b = Integer.parseInt(hex.substring(4, 6), 16);
            return new Color(r, g, b);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的十六进制颜色: " + hexColor, e);
        }
    }


}
